/* A simple server in the internet domain using TCP
   The port number is passed as an argument */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>



void error(const char *msg)
{
    perror(msg);
    //exit(1);
}



int readin(int fd, char * buffer, int size)
{
    int n = 0;
    n = recv(fd, buffer, size, MSG_WAITALL);
    if (n < 0)
	error("ERROR reading from socket");
    return n;
}

int gSpeed = 0;
enum Tachomode { pls, manual };
Tachomode gMode;

int getSpeed()
{
  return gSpeed;
}

void setSpeed(int speed)
{
  gSpeed = speed;
}

void setMode(Tachomode m)
{
  gMode = m;
}


int main(int argc, char *argv[])
{
     int sockfd, newsockfd, portno, clilen;
     struct sockaddr_in serv_addr, cli_addr;



     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided\n");
         exit(1);
     }

     portno = atoi(argv[1]);
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0)
        error("ERROR opening socket");

     memset((void *)&serv_addr, 0, sizeof(serv_addr));
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
     if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
        error("ERROR on binding");
     listen(sockfd,5);

     clilen = sizeof(cli_addr);
     

     if (newsockfd < 0)
          error("ERROR on accept");
     else
          printf("Connected\n");

     while(1)
     {
       printf("Wating to connect\n");
       newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t*)(&clilen));
       printf("Connected\n");
       while(1)
       {
         uint16_t * code  = new uint16_t;
         uint32_t * value = new uint32_t;

         int n  = readin(newsockfd, (char*)code,  sizeof(uint16_t));
	     n += readin(newsockfd, (char*)value, sizeof(uint32_t));
	 if(n == 0)
	 {
	    printf("Disconnected\n");
	    break;
	 }
         *code = ntohs(*code);
         *value = ntohl(*value);

         fprintf(stderr,"Here is the message %d %d\n", *code, *value);

         switch(*code)
         {
             case 0: // holle speed
                *code = 1;
                *code = htons(*code);
                *value = htonl(*value);
                send(newsockfd, (char*)code, sizeof(uint16_t),0);
                send(newsockfd, (char*)value, sizeof(uint32_t),0);
                break;
             case 1: // setzte speed
                setSpeed(*value);
                break;
	     case 2: // wechsel modus pls auf manuel
		if(*value == 0)
		  setMode(pls);
		else if(*value == 1)
		  setMode(manual);
		else
		{
		  //TODO: Fehler abfragen
		}
		break;
	     default:
	       //TODO: Fehler abfangen
	       break;
         }


         delete(code);
         delete(value);
       }
     }

     close(sockfd);
     return 0;
}
